package client.gui.panels;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Font;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;

import controllers.ClosureController;
import controllers.ControllerIF;
import controllers.EvaluationReportController;
import controllers.ReviewDecisionController;
import controllers.TimeFrameApprovalByInspectorController;
import controllers.TimeFrameRequestController;
import controllers.VerificationController;
import controllers.ViewTicketController;
import entities.Ticket;
import entities.User;

/**
 * @author Vodi
 * 
 */
public class ViewTicket extends JPanel implements PanelIF {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * the view ticket controller
	 */
	private ViewTicketController viewTicketController;

	/**
	 * A structure to hold all the information about a specific ticket
	 */
	private Ticket ticket;

	private User committeeChairmam;
	private List<User> committeeMembers;
	
	private Font promptFont = new Font("Times New Roman", Font.PLAIN, 16);

	// DO NOT REMOVE MY LABLE!!!!
	private JLabel ticketIdLabel;
	// Thanks...
	private JTabbedPane tabbedPane;
	private GeneralInformationPanel generalInfoPanel;
	private PanelIF evaluationPanel;
	private ReviewDecisionPanel reviewDecisionPanel;
	private PanelIF executionPanel;
	private PanelIF verificationPanel;
	private PanelIF closurePanel;

	/**
	 * Create the panel.
	 */
	public ViewTicket(Ticket ticket, ViewTicketController cif) {
		this.ticket = ticket;
		this.viewTicketController = cif;
		initGUI();
	}

	/**
	 * 
	 */
	public void initGUI() {

		setLayout(new BorderLayout(5, 5));
		{
			JPanel promptPanel = new JPanel();
			add(promptPanel, BorderLayout.NORTH);
			promptPanel.setLayout(new BoxLayout(promptPanel, BoxLayout.X_AXIS));

			promptPanel.add(Box.createHorizontalStrut(20));

			JLabel promptLabel = new JLabel("Details for ticket number ");
			promptLabel.setFont(promptFont);
			promptPanel.add(promptLabel);
			ticketIdLabel = new JLabel(ticket.getTicket_id().toString());
			ticketIdLabel.setFont(promptFont);
			promptPanel.add(ticketIdLabel);

			JLabel colonLabel = new JLabel(":");
			colonLabel.setFont(promptFont);
			promptPanel.add(colonLabel);

			promptPanel.add(Box.createHorizontalGlue());
		}

		{
			JPanel tabsPanel = new JPanel();
			tabsPanel.setBorder(new SoftBevelBorder(BevelBorder.RAISED, null, null, null, null));
			add(tabsPanel, BorderLayout.CENTER);
			tabsPanel.setLayout(new BoxLayout(tabsPanel, BoxLayout.X_AXIS));

			tabbedPane = new JTabbedPane(JTabbedPane.TOP);
			tabbedPane.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
			tabbedPane.setBorder(new BevelBorder(BevelBorder.RAISED, new Color(216, 191, 216), null, new Color(211, 211, 211), null));

			tabsPanel.add(tabbedPane);

			generalInfoPanel = new GeneralInformationPanel(ticket);
			tabbedPane.addTab("General information", null, generalInfoPanel, "General information about a ticket");

			/*
			 * Dynamically building the Evaluation step GUI
			 */
			DisplayEvaluationPanel();
			DisplayDecisionPanel();		
			DisplayExecutionPanel();
			DisplayVerificationPanel();
			DisplayClosurePanel();

		}
	}

	/**
	 * Set the evaluation panel according to current ticket state 
	 */
	public void DisplayEvaluationPanel() {
		Boolean needController = true;

		/*
		 * Step 1: The connected user is the ticket's evaluator AND The ticket
		 * is in "waiting for evaluation duration input" state:
		 */
		if (viewTicketController.getUser().getId().equals(ticket.getEvaluationReportStage().getEvaluator().getId())
				&& ticket.getState().equals("EVALUATION_DURATION")) {
			evaluationPanel = new TimeFrameRequest("evaluation");
			((TimeFrameRequest) evaluationPanel).setPanelEditable(true);
			viewTicketController.setInnerPanelController(new TimeFrameRequestController(viewTicketController, ticket));
		}

		/*
		 * Step 2: The connected user is the ticket's inspector AND The ticket
		 * is in "waiting for evaluation duration approval" state:
		 */
		else if (viewTicketController.getUser().getId().equals(ticket.getInspector().getId())
				&& ticket.getState().equals("EVALUATION_DURATION_APPROVAL")) {
			System.out.println("entering step 2");
			evaluationPanel = new TimeFrameApprovalByInspectorPanel(ticket.getEvaluationReportStage().getDurationDays(), ticket.getState());
			((TimeFrameApprovalByInspectorPanel)evaluationPanel).setPanelEditable(true);
			viewTicketController.setInnerPanelController(new TimeFrameApprovalByInspectorController(viewTicketController, ticket.getState()));
		}
		
		/*
		 * Step 3: The connected user is the ticket's evaluator AND The ticket
		 * is in "waiting for evaluation report" state:
		 */
		else if(viewTicketController.getUser().getId().equals(ticket.getEvaluationReportStage().getEvaluator().getId())	
				&& ticket.getState().equals("EVALUATION_REPORT")) {
			evaluationPanel = new EvaluationReportPanel(ticket);
			((EvaluationReportPanel)evaluationPanel).setPanelEditable(true);
			viewTicketController.setInnerPanelController(new EvaluationReportController(viewTicketController));
		}
		
		/*
		 * In case the user is not related to this stage OR the ticket's status is SUSPENDED
		 * all panels and text fields are not editable and there is no controller
		 */
		else {
			evaluationPanel = new EvaluationReportPanel(ticket);
			((EvaluationReportPanel) evaluationPanel).setPanelEditable(false);
			needController = false;
		}

		if(needController){
			evaluationPanel.setController(viewTicketController.getInnerPanelController());
			viewTicketController.getInnerPanelController().setPanel(evaluationPanel);
		}
		tabbedPane.addTab("Evaluation", null, (JPanel) evaluationPanel,	"Evaluation step");
	}

	/**
	 * Set the examining and decision panel according to current ticket state 
	 */
	public void DisplayDecisionPanel() {
		// start by getting the committee chairman 
		committeeChairmam = viewTicketController.getCommitteeChairmam();
		// build the panels
		System.out.println("ticket details (ID) are: " + ticket.getTicket_id());
		reviewDecisionPanel = new ReviewDecisionPanel(ticket.getReviewDecisionStage());
		viewTicketController.setInnerPanelController(new ReviewDecisionController(viewTicketController));
		reviewDecisionPanel.setController(viewTicketController.getInnerPanelController());
		viewTicketController.getInnerPanelController().setPanel(reviewDecisionPanel);
		tabbedPane.addTab("Review Decision", null, reviewDecisionPanel, "Examine & decision making step");
		// check if the connected user is the committee chairman
		if(viewTicketController.getUser().getId().equals(committeeChairmam.getId())) {
			reviewDecisionPanel.setEnabled(true);
		}
		else 
			reviewDecisionPanel.setEnabled(false);
	}

	/**
	 * Set the execution panel according to the current ticket's state
	 */
	public void DisplayExecutionPanel() {
		Boolean needController = true;

		/*
		 * Step 1: The connected user is the ticket's execution leader AND The ticket
		 * is in "waiting for execution duration input" state:
		 */
		if (viewTicketController.getUser().getId().equals(ticket.getExecutionStage().getLeader().getId())
				&& ticket.getState().equals("EXECUTION_DURATION")) {
			executionPanel = new TimeFrameRequest("execution");
			((TimeFrameRequest) executionPanel).setPanelEditable(true);
			viewTicketController.setInnerPanelController(new TimeFrameRequestController(viewTicketController, ticket));
		}

		/*
		 * Step 2: The connected user is the ticket's inspector AND The ticket
		 * is in "waiting for execution duration approval" state:
		 */
		else if (viewTicketController.getUser().getId().equals(ticket.getInspector().getId())
				&& ticket.getState().equals("EXECUTION_DURATION_APPROVAL")) {
			executionPanel = new TimeFrameApprovalByInspectorPanel(ticket.getExecutionStage().getDurationDays(), ticket.getState());
			((TimeFrameApprovalByInspectorPanel)executionPanel).setPanelEditable(true);
			viewTicketController.setInnerPanelController(new TimeFrameApprovalByInspectorController(viewTicketController, ticket.getState()));
		}
		
		/*
		 * Step 3: The connected user is the ticket's execution leader AND The ticket
		 * is in "waiting for execution report" state:
		 */
		else if(viewTicketController.getUser().getId().equals(ticket.getExecutionStage().getLeader().getId())
				&& ticket.getState().equals("EXECUTION_REPORT")) {
			executionPanel = new ExecutionPanel(ticket);
			((ExecutionPanel)executionPanel).setPanelEditable(true);
			viewTicketController.setInnerPanelController(new EvaluationReportController(viewTicketController));
		}
		
		/*
		 * In case the user is not related to this stage OR the ticket's status is SUSPENDED
		 * all panels and text fields are not editable and there is no controller
		 */
		else {
			executionPanel = new EvaluationReportPanel(ticket);
			((EvaluationReportPanel) executionPanel).setPanelEditable(false);
			needController = false;
		}

		if(needController){
			executionPanel.setController(viewTicketController.getInnerPanelController());
			viewTicketController.getInnerPanelController().setPanel(executionPanel);
		}
		tabbedPane.addTab("Evaluation", null, (JPanel) executionPanel,	"Evaluation step");
	}

	/**
	 * Set the verification panel according to the current ticket's state
	 */
	public void DisplayVerificationPanel() {
		
		// start by getting the committee members 
		committeeMembers = viewTicketController.getCommitteeMembers();
		
		if(viewTicketController.getUser().getId().equals(committeeChairmam.getId())
				&& !(ticket.getVerificationStage().getTester().equals(null))) {
			// the committee chairman is connected and there is no tester for this ticket
			viewTicketController.getInnerPanelController().setPanel(verificationPanel);
			verificationPanel.setController(viewTicketController.getInnerPanelController());
		}
		
		else if(committeeMembers.contains((User)viewTicketController.getUser())
				&& ticket.getVerificationStage().getTester().getId().equals(viewTicketController.getUser().getId())) {
			verificationPanel = new VerificationPanel();
			viewTicketController.setInnerPanelController(new VerificationController(viewTicketController));
			viewTicketController.getInnerPanelController().setPanel(verificationPanel);
			verificationPanel.setController(viewTicketController.getInnerPanelController());
		}
		else {
			verificationPanel = new VerificationPanel();
			((VerificationPanel) verificationPanel).setPanelEditable(false);
		}
		
		tabbedPane.addTab("Verification", null, (JPanel)verificationPanel, "Verification step");
	}
	
	/**
	 * Set the closure panel according to the current ticket's state
	 */
	public void DisplayClosurePanel() {
		closurePanel = new ClosurePanel(viewTicketController.getUser());
		viewTicketController.setInnerPanelController(new ClosureController(viewTicketController));
		closurePanel.setController(viewTicketController.getInnerPanelController());
		viewTicketController.getInnerPanelController().setPanel(closurePanel);
		
		
		if(viewTicketController.getUser().getId().equals(ticket.getInspector().getId()) || 
				viewTicketController.getUser().getId().equals(ticket.getTicketInitiator().getId())) {
			((ClosurePanel) closurePanel).setPanelEnabled(true);
		}
		((ClosurePanel) closurePanel).setPanelEnabled(false);
		
		tabbedPane.addTab("Closure", null, (JPanel) closurePanel, "Closure step");
	}
	
	public void setDefaultTab(int num) {
		tabbedPane.setSelectedIndex(num);
	}

	@Override
	public void setController(ControllerIF cif) {
		this.viewTicketController = (ViewTicketController) cif;
	}

}
